Clean up HVM relinquish_guest_resources interface and implementation.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 16 Mar 2006 18:36:28 +0000 (19:36 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 16 Mar 2006 18:36:28 +0000 (19:36 +0100)
Ensure we only unmap the shared I/O page after killing all timers
whose handlers may reference that page.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/domain.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/hvm.h
xen/include/asm-x86/hvm/svm/svm.h
xen/include/asm-x86/hvm/vmx/vmcs.h

index 836dc0e7078a1af85cda25a279059d1556ca292d..f5b5c14985e23ec7677dbc70133363953fcc04d2 100644 (file)
@@ -1030,11 +1030,11 @@ void domain_relinquish_resources(struct domain *d)
 
             v->arch.guest_table_user = mk_pagetable(0);
         }
-
-        if ( hvm_guest(v) )
-            hvm_relinquish_guest_resources(v);
     }
 
+    if ( hvm_guest(d->vcpu[0]) )
+        hvm_relinquish_guest_resources(d);
+
     shadow_mode_disable(d);
 
     /*
index cde1db4b602b9b12d5806ceca552f2efb9eb37b4..dffa5e8b81022d8797aa8bef935e5474d82e57f4 100644 (file)
@@ -77,6 +77,8 @@ void svm_manual_event_injection32(struct vcpu *v, struct cpu_user_regs *regs,
         int vector, int has_code);
 void svm_dump_regs(const char *from, struct cpu_user_regs *regs);
 
+static void svm_relinquish_guest_resources(struct domain *d);
+
 static struct asid_pool ASIDpool[NR_CPUS];
 
 /*
@@ -198,12 +200,6 @@ int svm_initialize_guest_resources(struct vcpu *v)
     return 1;
 }
 
-int svm_relinquish_guest_resources(struct vcpu *v)
-{
-    svm_relinquish_resources(v);
-    return 1;
-}
-
 void svm_store_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
@@ -722,43 +718,35 @@ void svm_final_setup_guest(struct vcpu *v)
 }
 
 
-void svm_relinquish_resources(struct vcpu *v)
+static void svm_relinquish_guest_resources(struct domain *d)
 {
-    struct hvm_virpit *vpit;
     extern void destroy_vmcb(struct arch_svm_struct *); /* XXX */
+    struct vcpu *v;
 
+    for_each_vcpu ( d, v )
+    {
 #if 0
-    /* 
-     * This is not stored at the moment. We need to keep it somewhere and free
-     * it Or maybe not, as it's a per-cpu-core item, and I guess we don't
-     * normally remove CPU's other than for hot-plug capable systems, where I
-     * guess we have to allocate and free host-save area in this case. Let's
-     * not worry about it at the moment, as loosing one page per CPU hot-plug
-     * event doesn't seem that excessive. But I may be wrong.
-     */
-    free_host_save_area(v->arch.hvm_svm.host_save_area);
+        /* Memory leak by not freeing this. XXXKAF: *Why* is not per core?? */
+        free_host_save_area(v->arch.hvm_svm.host_save_area);
 #endif
 
-    if ( v->vcpu_id == 0 )
-    {
-        /* unmap IO shared page */
-        struct domain *d = v->domain;
-        if ( d->arch.hvm_domain.shared_page_va )
-            unmap_domain_page_global(
-                (void *)d->arch.hvm_domain.shared_page_va);
-        shadow_direct_map_clean(d);
+        destroy_vmcb(&v->arch.hvm_svm);
+        free_monitor_pagetable(v);
+        kill_timer(&v->arch.hvm_svm.hlt_timer);
+        if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) 
+        {
+            kill_timer( &(VLAPIC(v)->vlapic_timer) );
+            xfree(VLAPIC(v));
+        }
     }
 
-    destroy_vmcb(&v->arch.hvm_svm);
-    free_monitor_pagetable(v);
-    vpit = &v->domain->arch.hvm_domain.vpit;
-    kill_timer(&vpit->pit_timer);
-    kill_timer(&v->arch.hvm_svm.hlt_timer);
-    if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) ) 
-    {
-        kill_timer( &(VLAPIC(v)->vlapic_timer) );
-        xfree( VLAPIC(v) );
-    }
+    kill_timer(&d->arch.hvm_domain.vpit.pit_timer);
+
+    if ( d->arch.hvm_domain.shared_page_va )
+        unmap_domain_page_global(
+            (void *)d->arch.hvm_domain.shared_page_va);
+
+    shadow_direct_map_clean(d);
 }
 
 
index 0b3d9a8205d5f0ddb122e2cf048069006e760fa8..117a95f85e8e15b0a5d95e1e20efade99f28aa34 100644 (file)
@@ -78,30 +78,30 @@ void vmx_final_setup_guest(struct vcpu *v)
     }
 }
 
-void vmx_relinquish_resources(struct vcpu *v)
+static void vmx_relinquish_guest_resources(struct domain *d)
 {
-    struct hvm_virpit *vpit;
+    struct vcpu *v;
 
-    if (v->vcpu_id == 0) {
-        /* unmap IO shared page */
-        struct domain *d = v->domain;
-        if ( d->arch.hvm_domain.shared_page_va )
-            unmap_domain_page_global(
-               (void *)d->arch.hvm_domain.shared_page_va);
-        shadow_direct_map_clean(d);
-    }
-
-    vmx_request_clear_vmcs(v);
-    destroy_vmcs(&v->arch.hvm_vmx);
-    free_monitor_pagetable(v);
-    vpit = &v->domain->arch.hvm_domain.vpit;
-    kill_timer(&vpit->pit_timer);
-    kill_timer(&v->arch.hvm_vmx.hlt_timer);
-    if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
+    for_each_vcpu ( d, v )
     {
-        kill_timer(&VLAPIC(v)->vlapic_timer);
-        xfree(VLAPIC(v));
+        vmx_request_clear_vmcs(v);
+        destroy_vmcs(&v->arch.hvm_vmx);
+        free_monitor_pagetable(v);
+        kill_timer(&v->arch.hvm_vmx.hlt_timer);
+        if ( hvm_apic_support(v->domain) && (VLAPIC(v) != NULL) )
+        {
+            kill_timer(&VLAPIC(v)->vlapic_timer);
+            xfree(VLAPIC(v));
+        }
     }
+
+    kill_timer(&d->arch.hvm_domain.vpit.pit_timer);
+
+    if ( d->arch.hvm_domain.shared_page_va )
+        unmap_domain_page_global(
+               (void *)d->arch.hvm_domain.shared_page_va);
+
+    shadow_direct_map_clean(d);
 }
 
 #ifdef __x86_64__
@@ -326,12 +326,6 @@ int vmx_initialize_guest_resources(struct vcpu *v)
     return 1;
 }
 
-int vmx_relinquish_guest_resources(struct vcpu *v)
-{
-    vmx_relinquish_resources(v);
-    return 1;
-}
-
 void vmx_migrate_timers(struct vcpu *v)
 {
     struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
index 5df87f90ea2fa58771f95b63873bf46a0c8d7f03..5fe4aed846c3dee715e258d3d3c12c7f70893d60 100644 (file)
@@ -35,8 +35,8 @@ struct hvm_function_table {
     /*
      * Initialize/relinguish HVM guest resources
      */
-    int (*initialize_guest_resources)(struct vcpu *v);
-    int (*relinquish_guest_resources)(struct vcpu *v);
+    int  (*initialize_guest_resources)(struct vcpu *v);
+    void (*relinquish_guest_resources)(struct domain *d);
 
     /*
      * Store and load guest state:
@@ -80,24 +80,23 @@ extern struct hvm_function_table hvm_funcs;
 static inline void
 hvm_disable(void)
 {
-    if (hvm_funcs.disable)
-       hvm_funcs.disable();
+    if ( hvm_funcs.disable )
+        hvm_funcs.disable();
 }
 
 static inline int
 hvm_initialize_guest_resources(struct vcpu *v)
 {
-    if (hvm_funcs.initialize_guest_resources)
-       return hvm_funcs.initialize_guest_resources(v);
+    if ( hvm_funcs.initialize_guest_resources )
+        return hvm_funcs.initialize_guest_resources(v);
     return 0;
 }
 
-static inline int
-hvm_relinquish_guest_resources(struct vcpu *v)
+static inline void
+hvm_relinquish_guest_resources(struct domain *d)
 {
     if (hvm_funcs.relinquish_guest_resources)
-       return hvm_funcs.relinquish_guest_resources(v);
-    return 0;
+        hvm_funcs.relinquish_guest_resources(d);
 }
 
 static inline void
@@ -134,9 +133,9 @@ hvm_restore_msrs(struct vcpu *v)
         hvm_funcs.restore_msrs(v);
 }
 #else
-#define        hvm_save_segments(v)    ((void)0)
-#define        hvm_load_msrs(v)        ((void)0)
-#define        hvm_restore_msrs(v)     ((void)0)
+#define hvm_save_segments(v)    ((void)0)
+#define hvm_load_msrs(v)        ((void)0)
+#define hvm_restore_msrs(v)     ((void)0)
 #endif /* __x86_64__ */
 
 static inline void
index c6c848ec9034b1383de0043ea57aa28f69db9041..16c7decbb2fab2faf3cfab2e24d32c860a648b1b 100644 (file)
@@ -44,7 +44,6 @@ extern void svm_vmread(struct vcpu *v, int index, unsigned long *value);
 extern void svm_vmwrite(struct vcpu *v, int index, unsigned long value);
 extern void svm_final_setup_guest(struct vcpu *v); 
 extern int svm_paging_enabled(struct vcpu *v); 
-extern void svm_relinquish_resources(struct vcpu *v);
 extern void svm_dump_vmcb(const char *from, struct vmcb_struct *vmcb);
 extern void svm_stts(struct vcpu *v); 
 extern void svm_do_launch(struct vcpu *v);
index 081b64d77399555947dfad5959a6d44bc2846a9f..f79f7a4c8b347fb4ff82638c86514ec166d4c0ce 100644 (file)
@@ -28,7 +28,6 @@ extern int start_vmx(void);
 extern void stop_vmx(void);
 
 void vmx_final_setup_guest(struct vcpu *v);
-void vmx_relinquish_resources(struct vcpu *v);
 
 void vmx_enter_scheduler(void);